home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 July: Mac OS SDK / Dev.CD Jul 00 SDK2.toast / Development Kits / Hardware / Mac OS USB DDK / Mac OS USB DDK 1.4.1 / USB Software Locator Kit / SampleDriverInstallerExample / SampleDriver.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-04-25  |  9.3 KB  |  282 lines  |  [TEXT/CWIE]

  1. /*
  2.     File:        SampleDriver.c
  3.  
  4.     Contains:    Driver for Sample USB device
  5.  
  6.     Version:    xxx put version here xxx
  7.  
  8.     Copyright:    © 1997-1998 by Apple Computer, Inc., all rights reserved.
  9.  
  10.  
  11.     Writers:
  12.  
  13.         (CJK)    Craig Keithley
  14.  
  15.     Change History (most recent first):
  16.  
  17. */
  18.  
  19. #include <Types.h>
  20. #include <Devices.h>
  21. #include <processes.h>
  22. #include <DriverServices.h>
  23. #include <USB.h>
  24.  
  25. #include "SampleDriver.h"
  26. #include "hex2c.h"
  27.  
  28. extern    INTEL_HEX_RECORD bulktest[];
  29.  
  30. usbSamplePBStruct mySamplePB;
  31.  
  32. void InitParamBlock(USBDeviceRef theDeviceRef, USBPB * paramblock)
  33. {
  34.     paramblock->usbReference = theDeviceRef;
  35.     paramblock->pbVersion = kUSBCurrentPBVersion;
  36.     paramblock->usbStatus = noErr;
  37.     paramblock->usbBuffer = nil;        
  38.     paramblock->usbActCount = 0;
  39.     paramblock->usbReqCount = 0;
  40.     paramblock->usbFlags = 0;
  41.     paramblock->usbOther = 0;
  42. }
  43.  
  44.  
  45.  
  46. Boolean immediateError(OSStatus err)
  47. {
  48.     return((err != kUSBPending) && (err != noErr) );
  49. }
  50.  
  51. void InitiateTransactionProc(USBPB *pb)
  52. {
  53. register usbSamplePBStruct *pSamplePB;
  54. OSStatus myErr;
  55.  
  56.     pSamplePB = (usbSamplePBStruct *)(pb);
  57.     pSamplePB->transDepth++;
  58.     if (pSamplePB->transDepth < 0)
  59.     {
  60.         USBExpertFatalError(pSamplePB->deviceRef, kUSBInternalErr, kDriverName": transDepth < 0 (initiation)", pSamplePB->pb.usbRefcon );
  61.     }
  62.     
  63.     if (pSamplePB->transDepth > 1)
  64.     {
  65.         USBExpertFatalError(pSamplePB->deviceRef, kUSBInternalErr, kDriverName": transDepth > 1 (initiation)", pSamplePB->pb.usbRefcon );
  66.     }
  67.     
  68.     switch(pSamplePB->pb.usbRefcon & ~kRetryTransaction)
  69.     {
  70.         case kFindInterface:
  71.             InitParamBlock(pSamplePB->deviceRef, &pSamplePB->pb);
  72.             pSamplePB->pb.usb.cntl.WIndex = 0;
  73.             pSamplePB->pb.usb.cntl.WValue = 0;
  74.             pSamplePB->pb.usbClassType = 0xff;
  75.             pSamplePB->pb.usbSubclass = 0xff;
  76.             pSamplePB->pb.usbProtocol = 0xff;
  77.             pSamplePB->pb.usbRefcon |= kCompletionPending;
  78.             pSamplePB->pb.usbCompletion = (USBCompletion)TransactionCompletionProc;
  79.             myErr = USBFindNextInterface(pb);
  80.             if(immediateError(myErr))
  81.             {
  82.                 USBExpertFatalError(pSamplePB->pb.usbReference, kUSBInternalErr, kDriverName": USBFindNextInterface (immediate error)", myErr);
  83.                 pSamplePB->pb.usbRefcon = kReturnFromDriver;
  84.             }
  85.             break;
  86.             
  87.         case kOpenDevice:
  88.             InitParamBlock(pSamplePB->deviceRef, &pSamplePB->pb);
  89.             pSamplePB->pb.usb.cntl.WValue = pSamplePB->configurationNumber;
  90.             pSamplePB->pb.usbRefcon |= kCompletionPending;
  91.             
  92.             pSamplePB->pb.usbCompletion = (USBCompletion)TransactionCompletionProc;
  93.             myErr = USBOpenDevice(pb);
  94.             if(immediateError(myErr))
  95.             {
  96.                 USBExpertFatalError(pSamplePB->pb.usbReference, kUSBInternalErr, kDriverName": USBOpenDevice (immediate error)", myErr);
  97.                 pSamplePB->pb.usbRefcon = kReturnFromDriver;
  98.             }
  99.             break;
  100.             
  101.             case kAssert8051Reset:
  102.                 USBExpertStatus(pSamplePB->deviceRef, kDriverName": Asserting 8051 Reset", pSamplePB->deviceRef);
  103.                 pSamplePB->writeBuffer[0] = 0x01;
  104.                 myErr = SampleWrite(&pSamplePB->pb, k8051_USBCS, 1, pSamplePB->writeBuffer);
  105.                 if(immediateError(myErr))
  106.                 {
  107.                     USBExpertFatalError(pSamplePB->deviceRef, kUSBInternalErr, kDriverName": Assert 8051 Reset - immediate error", myErr);
  108.                 }
  109.                 break;
  110.                 
  111.             case kDownload8051Firmware:
  112.                 USBExpertStatus(bulktest[pSamplePB->recordnum].Address, kDriverName": Downloading record", pSamplePB->recordnum);
  113.                 myErr = SampleWrite(&pSamplePB->pb, bulktest[pSamplePB->recordnum].Address, bulktest[pSamplePB->recordnum].Length, bulktest[pSamplePB->recordnum].Data);
  114.                 if(immediateError(myErr))
  115.                 {
  116.                     USBExpertFatalError(pSamplePB->deviceRef, kUSBInternalErr, kDriverName": Download Firmware - immediate error", myErr);
  117.                 }
  118.                 break;
  119.                 
  120.             case kNegate8051Reset:
  121.                 USBExpertStatus(pSamplePB->deviceRef, kDriverName": Negating 8051 Reset", pSamplePB->deviceRef);
  122.                 pSamplePB->writeBuffer[0] = 0x00;
  123.                 myErr = SampleWrite(&pSamplePB->pb, k8051_USBCS, 1, pSamplePB->writeBuffer);
  124.                 if(immediateError(myErr))
  125.                 {
  126.                     USBExpertFatalError(pSamplePB->deviceRef, kUSBInternalErr, kDriverName": Negate 8051 Reset - immediate error", myErr);
  127.                 }
  128.                 break;
  129.                 
  130.         default:
  131.             USBExpertFatalError(pSamplePB->deviceRef, kUSBInternalErr, kDriverName": Transaction initiated with bad refcon value", pSamplePB->pb.usbRefcon);
  132.             pSamplePB->pb.usbRefcon = kUndefined + kReturnFromDriver;
  133.             break;
  134.     }
  135.     
  136. // At this point the control is returned to the system.  If a USB transaction
  137. // has been initiated, then it will call the Complete procs
  138. // (below) to handle the results of the transaction.
  139. }
  140.  
  141.  
  142. void TransactionCompletionProc(USBPB *pb)
  143. {
  144. register usbSamplePBStruct *pSamplePB;
  145. unsigned char    * errstring;
  146. USBPipeState     pipeState;
  147.  
  148.     pSamplePB = (usbSamplePBStruct *)(pb);
  149.     pSamplePB->transDepth--;
  150.     if (pSamplePB->transDepth < 0)
  151.     {
  152.         USBExpertFatalError(pSamplePB->deviceRef, kUSBInternalErr, kDriverName": transDepth < 0 (completion)", pSamplePB->pb.usbRefcon );
  153.     }
  154.     
  155.     if (pSamplePB->transDepth > 1)
  156.     {
  157.         USBExpertFatalError(pSamplePB->deviceRef, kUSBInternalErr, kDriverName": transDepth > 1 (completion)", pSamplePB->pb.usbRefcon );
  158.     }
  159.     
  160.     if(pSamplePB->pb.usbStatus != noErr)                                                    // was there an error?
  161.     {
  162.         switch(pSamplePB->pb.usbRefcon & 0x0fff)                                            // yes, so show where the error occurred
  163.         {
  164.             case kFindInterface:                  errstring = kDriverName": Error during kFindInterface"; break;
  165.             case kOpenDevice:                    errstring = kDriverName": Error during kOpenDevice"; break;
  166.             case kAssert8051Reset:                errstring = kDriverName": Error during kAssert8051Reset"; break;
  167.             case kDownload8051Firmware:            errstring = kDriverName": Error during kDownload8051Firmware"; break;
  168.             case kNegate8051Reset:                errstring = kDriverName": Error during kNegate8051Reset"; break;
  169.             default:                              errstring = kDriverName": Error occurred, but state is unknown"; break;
  170.         };
  171.         USBExpertFatalError(pSamplePB->deviceRef, pSamplePB->pb.usbStatus, errstring, (pSamplePB->pb.usbRefcon & 0x0fff));
  172.         
  173.         pSamplePB->pb.usbRefcon &= ~(kCompletionPending + kReturnFromDriver);                // set up to retry the transaction
  174.         pSamplePB->pb.usbRefcon |= kRetryTransaction;
  175.         pSamplePB->retryCount--;
  176.         
  177.         if ((!pSamplePB->retryCount)    || (pSamplePB->pb.usbStatus == kUSBAbortedError))    // have we exhausted the retries?
  178.         {                                                                                    // or received an abort?
  179.             USBExpertStatus(pSamplePB->deviceRef, kDriverName": Pipe abort or unable to recover from error", pSamplePB->deviceRef);
  180.             pSamplePB->pb.usbRefcon = kReturnFromDriver;                                    // if so, just exit.
  181.         }
  182.         else                                                                                // if it didn't abort and there's retries left, then...
  183.         {
  184.             if (pSamplePB->pipeRef)                                                            // check if the pipe is open.
  185.             {
  186.                 USBGetPipeStatusByReference(pSamplePB->pipeRef, &pipeState);                // yes, so what it's state?
  187.                 if (pipeState != kUSBActive)                                                // if it's not active, try to clear it.  It might be stalled...
  188.                 {
  189.                     USBExpertStatus(pSamplePB->deviceRef, kDriverName": Pipe is open and stalled, clearing stall...", pSamplePB->deviceRef);
  190.                     USBClearPipeStallByReference(pSamplePB->pipeRef);
  191.                 }
  192.             }
  193.         }
  194.     }
  195.     else
  196.     {
  197.         pSamplePB->pb.usbRefcon &= ~kRetryTransaction;
  198.         pSamplePB->retryCount = kSampleRetryCount;
  199.     }
  200.  
  201.     if (pSamplePB->pb.usbRefcon & kCompletionPending)             
  202.     {                                                
  203.         pSamplePB->pb.usbRefcon &= ~(kCompletionPending + kReturnFromDriver);
  204.         switch(pSamplePB->pb.usbRefcon)
  205.         {
  206.             case kFindInterface:
  207.                 if ((pSamplePB->pb.usbClassType == 0xff) && 
  208.                     (pSamplePB->pb.usbSubclass == 0xff) &&
  209.                     (pSamplePB->pb.usbProtocol == 0xff))
  210.                 {
  211.                     USBExpertStatus(pSamplePB->deviceRef, kDriverName": Found Interface (0 endpoints)", pSamplePB->deviceRef);
  212.                     pSamplePB->interfaceNumber = pSamplePB->pb.usb.cntl.WIndex;
  213.                     pSamplePB->configurationNumber = pSamplePB->pb.usb.cntl.WValue;
  214.                     pSamplePB->pb.usbRefcon = kOpenDevice;
  215.                 }
  216.                 else
  217.                 {
  218.                     pSamplePB->pb.usbRefcon = kReturnFromDriver;
  219.                 }
  220.                 break;
  221.                 
  222.             case kOpenDevice:
  223.                 pSamplePB->pb.usbRefcon = kAssert8051Reset;
  224.                 break;
  225.                 
  226.             case kAssert8051Reset:
  227.                 USBExpertStatus(pSamplePB->deviceRef, kDriverName": Reset asserted", pSamplePB->deviceRef);
  228.                 pSamplePB->recordnum = 0;
  229.                 pSamplePB->pb.usbRefcon = kDownload8051Firmware;
  230.                 break;
  231.                 
  232.             case kDownload8051Firmware:
  233.                 pSamplePB->recordnum++;
  234.                 if (bulktest[pSamplePB->recordnum].Type)
  235.                 {
  236.                     USBExpertStatus(pSamplePB->deviceRef, kDriverName": 8051 Firmware download complete", pSamplePB->deviceRef);
  237.                     pSamplePB->pb.usbRefcon = kNegate8051Reset;
  238.                 }
  239.                 else
  240.                 {
  241.                     pSamplePB->pb.usbRefcon = kDownload8051Firmware;
  242.                 }
  243.                 break;
  244.                 
  245.             case kNegate8051Reset:
  246.                 USBExpertStatus(pSamplePB->deviceRef, kDriverName": Reset negated", pSamplePB->deviceRef);
  247.                 pSamplePB->pb.usbRefcon = kReturnFromDriver;
  248.                 break;
  249.                 
  250.                 
  251.         }
  252.     }
  253.     if (!(pSamplePB->pb.usbRefcon & kReturnFromDriver))
  254.         InitiateTransactionProc(pb);
  255. }
  256.  
  257. OSStatus    SampleWrite(USBPB *pb, UInt32 driverAddress, UInt32 count, UInt8 writeBuffer[])
  258. {
  259. register     usbSamplePBStruct *pSamplePB;
  260. OSStatus     myErr = kUSBNoErr;
  261.  
  262.     pSamplePB = (usbSamplePBStruct *)(pb);
  263.  
  264.     InitParamBlock(pSamplePB->deviceRef, &pSamplePB->pb);
  265.     pSamplePB->pb.usb.cntl.BMRequestType = USBMakeBMRequestType(kUSBOut, kUSBVendor, kUSBDevice);            
  266.     
  267.     pSamplePB->pb.usb.cntl.BRequest = 0xa0;
  268.     pSamplePB->pb.usb.cntl.WValue = driverAddress; 
  269.     pSamplePB->pb.usb.cntl.WIndex = 0x00;
  270.     
  271.     pSamplePB->pb.usbBuffer = (Ptr)&writeBuffer[0];
  272.     pSamplePB->pb.usbReqCount = count;
  273.         
  274.     pSamplePB->pb.usbCompletion = (USBCompletion)TransactionCompletionProc;
  275.     pSamplePB->pb.usbRefcon |= kCompletionPending;
  276.     
  277.     myErr = USBDeviceRequest(&pSamplePB->pb);
  278.     return myErr;
  279. }
  280.  
  281.  
  282.